using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Orchid.Blazor.Hosting.Repositories;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Orchid.Blazor.Hosting.Server
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var rootDirectory = new DirectoryInfo(Path.Combine(new FileInfo(Assembly.GetEntryAssembly().Location).DirectoryName, "Webs"));
            if (!rootDirectory.Exists) rootDirectory.Create();
            
            var repostories = new List<WebRepository>();
            repostories.AddRange(WebDirectoryRepository.GetRepostories(rootDirectory));
            repostories.AddRange(WebArchiveRepository.GetRepostories(rootDirectory));

            Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(hostBuilder =>
            {
                hostBuilder.UseKestrel();
                hostBuilder.Configure(app =>
                {
                    foreach (var repository in repostories) app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments($"/{repository.Name}"), webApp =>
                      {
                          webApp.Use(next => async ctx =>
                            {
                                ctx.Request.Path = ctx.Request.Path.Value.Substring(repository.Name.Length + 1);
                                if (!ctx.Request.Path.HasValue) ctx.Request.Path = "/";
                                await next?.Invoke(ctx);
                            });
                          webApp.Use(next => async ctx => await repository.Executor.Invoke(ctx));
                      });

                    var defaultRepository = new WebDirectoryRepository(rootDirectory, isRoot: true);
                    app.Use(next => async ctx => await defaultRepository.Executor.Invoke(ctx));

                    var lifetime = app.ApplicationServices.GetService<IHostApplicationLifetime>();
                    lifetime.ApplicationStopping.Register(() =>
                    {
                        foreach (var repository in repostories) repository.Dispose();
                        defaultRepository.Dispose();
                    });
                });
            }).Build().Run();
        }
    }
}
